package cn.you.GenghisKhan.common.parser;

import java.io.File;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.you.GenghisKhan.common.utils.XmlUtils;
import org.w3c.dom.Element;

public class XmlConverter {
	public <T> T toResponse(File rsp, Class<T> clazz) throws Exception {
		Element root = XmlUtils.getRootElementFromFile(rsp);
		return getModelFromXML(root, clazz);
	}

	public <T> T toResponse(String rsp, Class<T> clazz) throws Exception {
		Element root = XmlUtils.getRootElementFromString(rsp);
		return getModelFromXML(root, clazz);
	}

	private <T> T getModelFromXML(final Element element, Class<T> clazz)
			throws Exception {
		if (element == null) {
			return null;
		}
		return Converters.convert(clazz, new Reader() {
			public boolean hasReturnField(Object name) {
				Element childE = XmlUtils.getChildElement(element,
						(String) name);
				return childE != null;
			}

			public Object getPrimitiveObject(Object name) {
				return XmlUtils.getChildElementValue(element, (String) name);
			}

			public Object getObject(Object name, Class<?> type)
					throws Exception {
				Element childE = XmlUtils.getChildElement(element,
						(String) name);
				if (childE != null) {
					return XmlConverter.this.getModelFromXML(childE, type);
				}
				return null;
			}

			public List<?> getListObjects(Object listName, Object itemName,
					Class<?> subType,List<ObjectConfig>objectlist) throws Exception {
				List<Object> list = null;
				Element listE = XmlUtils.getChildElement(element,
						(String) listName);
				if (listE != null) {
					list = new ArrayList();
					List<Element> itemEs = XmlUtils.getChildElements(listE,
							(String) itemName);
					for (Element itemE : itemEs) {
						Object obj = null;
						String value = XmlUtils.getElementValue(itemE);
						if (String.class.isAssignableFrom(subType)) {
							obj = value;
						} else if (Long.class.isAssignableFrom(subType)) {
							obj = Long.valueOf(value);
						} else if (Integer.class.isAssignableFrom(subType)) {
							obj = Integer.valueOf(value);
						} else if (Boolean.class.isAssignableFrom(subType)) {
							obj = Boolean.valueOf(value);
						} else if (Date.class.isAssignableFrom(subType)) {
							DateFormat format = new SimpleDateFormat(
									"yyyy-MM-dd HH:mm:ss");
							try {
								obj = format.parse(value);
							} catch (ParseException e) {
								throw e;
							}
						} else {
							obj = XmlConverter.this.getModelFromXML(itemE,
									subType);
						}
						if (obj != null) {
							list.add(obj);
						}
					}
				}
				return list;
			}
		});
	}
}